"""
Few-Shot Learning with Chain-of-Thought 示例

本代码演示如何使用LangChain构建包含思维链推理的few-shot提示：
1. 通过多个示例展示复杂问题的分步推理过程
2. 教会大模型如何拆解复杂问题、跟进子问题
3. 最终生成结构化的推理过程和答案

关键概念：
- Few-Shot Learning: 提供少量示例让模型学习任务模式
- Chain-of-Thought: 分步推理，展示思考过程
- PromptTemplate: 定义输入输出格式的模板
- FewShotPromptTemplate: 组合多个示例生成完整提示
"""

from langchain.prompts.few_shot import FewShotPromptTemplate
from langchain.prompts.prompt import PromptTemplate

# 定义few-shot示例集合 - 每个示例展示问题拆解和思维链推理过程
examples = [
    {
        "question": "谁的寿命更长，穆罕默德·阿里还是艾伦·图灵",
        "answer":
            """
                这里需要跟进问题吗：是的。
                跟进：穆罕默德·阿里去世时多大？
                中间答案：穆罕默德·阿里去世时74岁。
                跟进：艾伦·图灵去世时多大？
                中间答案：艾伦·图灵去世时41岁。
                所以最终答案是：穆罕默德·阿里
            """
    }, {
        "question": "肯德基的创始人是什么时候出生的？",
        "answer":
            """
                这里需要跟进问题吗：是的。
                跟进：肯德基的创始人是谁？
                中间答案：肯德基由肯德基上校创立。
                跟进：肯德基上校是什么时候出生的？
                中间答案：肯德基上校于1933年4月2日出生。
                所以最终答案是：1933年4月2日。
            """
    }, {
        "question": "《大白鲨》和《皇家赌场》的导演都来自同一个国家吗？",
        "answer":
            """
            这里需要跟进问题吗：是的。
            跟进：《大白鲨》的导演是谁？
            中间答案：《大白鲨》的导演是Steven Spielberg。
            跟进：Steven Spielberg来自哪里？
            中间答案：美国。
            跟进：《皇家赌场》的导演是谁？
            中间答案：《皇家赌场》的导演是Martin Campbell。
            跟进：Martin Campbell来自哪里？
            中间答案：新西兰。
            所以最终答案是：不是
            """
    }
]

# 创建单个示例的格式化模板 - 定义问题和答案的展示格式
example_prompt = PromptTemplate(
    input_variables=["question", "answer"],  # 模板输入变量：从examples中提取
    template="问题：{question}\n{answer}"     # 模板格式：问题 + 换行 + 思维链答案
)

# 测试模板格式化效果 - 查看单个示例的渲染结果
print("=== 单个示例格式化结果 ===")
print(example_prompt.format(**examples[0]))  # **解包字典：question=..., answer=...
print()

# 创建FewShot提示模板 - 组合所有示例并添加用户问题
prompt = FewShotPromptTemplate(
    examples=examples,           # 示例集合：作为模型的参考样本
    example_prompt=example_prompt, # 单个示例模板：定义每个示例的格式
    suffix="问题：{input}",       # 后缀：在所有示例后添加用户的实际问题
    input_variables=["input"],   # 输入变量：用户问题的占位符
)

# 生成完整提示 - 将用户问题插入到few-shot模板中
print("=== 完整Few-Shot提示 ===")
formatted_prompt = prompt.format(input="奥巴马和克林顿谁的年龄更大？")
print(formatted_prompt)